#pragma once
#include "FAQ.h"
#include "array/Array.hpp"


namespace yzrilyzr_crypto{
	EBCLASS(CryptoUtil){
	public:
	static void xor (const yzrilyzr_array::ByteArray & a, const yzrilyzr_array::ByteArray & b, yzrilyzr_array::ByteArray & out){
		if(a.length != b .length||a.length!=out.length){
			throw yzrilyzr_lang::IllegalArgumentException();
		}
		for(int i=0;i < out.length;i++){
			out[i]=a[i]^b [i];
		}
	}
	static yzrilyzr_array::ByteArray xorMinLength(const yzrilyzr_array::ByteArray & a, const yzrilyzr_array::ByteArray & b, yzrilyzr_array::ByteArray & out){
		u_index minL=yzrilyzr_lang::Math::min(a.length, b.length);
		if(out.length != minL)out=yzrilyzr_array::ByteArray(minL);
		for(int i=0;i < minL;i++){
			out[i]=a[i] ^ b[i];
		}
		return out;
	}
	/**
	 * Constant-time comparison of two byte arrays (compares full length)
	 *
	 * @param a first byte array
	 * @param b second byte array
	 * @return true if arrays are equal, false otherwise
	 */
	static bool constantTimeEquals(const yzrilyzr_array::ByteArray & a, const yzrilyzr_array::ByteArray & b){
		if(a == nullptr || b == nullptr){
			return false;
		}
		if(a.length != b.length){
			return false;
		}
		return constantTimeEquals(a, b, a.length);
	}
	/**
	 * Constant-time comparison of two byte arrays to prevent timing attacks
	 *
	 * @param a   first byte array
	 * @param b   second byte array
	 * @param len number of bytes to compare
	 * @return true if arrays are equal, false otherwise
	 */
	static bool constantTimeEquals(const yzrilyzr_array::ByteArray & a, const yzrilyzr_array::ByteArray & b, u_index len){
		if(a == nullptr || b == nullptr){
			return false;
		}
		if(a.length < len || b.length < len){
			return false;
		}
		int32_t result=0;
		// Compare all bytes regardless of content
		for(int32_t i=0;i < len;i++){
			result|=a[i] ^ b[i];
		}
		return result == 0;
	}
	};
}